from google.appengine.ext import db
from datetime import date
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
import logging
import random

class Contacts(db.Model):
  member_id = db.StringProperty(required=True)
  contact_list = db.StringListProperty(required=True)
  high_score = db.IntegerProperty()
  name = db.StringProperty()

class Person(db.Model):
  member_id = db.StringProperty(required=True)
  first_name = db.StringProperty(required=True)
  last_name = db.StringProperty(required=True)
  connection_list = db.ReferenceProperty(Contacts)
  publications = db.StringListProperty()
  patents = db.StringListProperty()
  languages = db.StringListProperty()
  skills = db.StringListProperty()
  certifications = db.StringListProperty()
  twitter_accounts = db.StringListProperty()
  date_of_birth = db.DateProperty()
  address = db.TextProperty()
  pic_url = db.StringProperty(required=True)
  educations = db.StringListProperty()
  positions = db.StringListProperty()
  
def getMembersNeeded(memberId, connections, fullName):
  contact_list = []
  
  #List of members we need details for
  need_deets = []
  
  for conn in connections['values']:
    #query to check if person already in datastore
    mem_id = conn['id']
    if 'pictureUrl' in conn:
      contact_list.append(mem_id)
      if not inDatastore(mem_id):
        need_deets.append(mem_id)
  
  contacts = Contacts(key_name=str(memberId),member_id=memberId, contact_list=contact_list,high_score=0,name=fullName)
  contacts.put()  
  logging.error("Returning list of members to get details for of size: " + str(len(need_deets)))
  return need_deets
  
def populateDatastore(deets):
  #add deets to datastore
  for profile in deets['values']:
    memId = profile['id']
    logging.error("memId should not be same every time!!! " + memId)
    fn = profile['firstName']
    ln = profile['lastName']
    pic = profile['pictureUrls']['values'][0]
    score = 0
    
    """
    contacts = Contacts.get_by_key_name(memId)
    query = db.Query(contacts)
    result = query.fetch(limit=1)
    connections = result[0].contact_list
    """
    
    dude = Person(key_name=str(memId),member_id=str(memId), first_name=str(fn), last_name=str(ln),pic_url=str(pic),high_score=score)
    
    if 'publications' in profile and not profile['publications']['_total'] == 0:
      pubs = [x['title'] for x in profile['publications']['values']]
      dude.publications = pubs
    
    if 'patents' in profile and not profile['patents']['_total'] == 0:
      pats = [x['title'] for x in profile['patents']['values']]
      dude.patents = pats
      
    if 'languages' in profile and not profile['languages']['_total'] == 0:
      langs = [x['language']['name'] for x in profile['languages']['values']]
      dude.languages = langs
      
    if 'skills' in profile and not profile['skills']['_total'] == 0:
      skills = [x['skill']['name'] for x in profile['skills']['values']]
      dude.skills = skills

    if 'certifications' in profile and not profile['certifications']['_total'] == 0:
      cert = [x['name'] for x in profile['certifications']['values']]
      dude.certifications = cert
    
    if 'twitterAccounts' in profile and not profile['twitterAccounts']['_total'] == 0:
      twat = [x['providerAccountName'] for x in profile['twitterAccounts']['values']]
      dude.twitter_accounts = twat
    
    #DOB
    if 'dateOfBirth' in profile:
      if 'year' in profile['dateOfBirth'] and 'month' in profile['dateOfBirth'] and 'day' in profile['dateOfBirth']:
        yr = profile['dateOfBirth']['year']
        month = profile['dateOfBirth']['month']
        day = profile['dateOfBirth']['day']
        dob = date(yr, month, day)
        dude.date_of_birth = dob
    
    if 'mainAddress' in profile:
      addr = profile['mainAddress']
      dude.address = addr
    
    if 'educations' in profile and not profile['educations']['_total'] == 0:
      edus = [x['schoolName'] for x in profile['educations']['values']]
      dude.educations = edus
    
    if 'positions' in profile and not profile['positions']['_total'] == 0:
      posns = []
      for x in profile['positions']['values']:
        try:
          posns.append(x['company']['name'])
        except:
          pass
      dude.positions = posns
      
    dude.put()
    
  
def inDatastore(memberId):
  query = Person.all()
  query.filter('member_id =', memberId)
  result = query.fetch(limit=1)
  if len(result) == 0:
    logging.error(memberId + " is not in the datastore")
    return False
  try:
    stuff = result[0].member_id
    logging.error(memberId + " is already in the datastore: " + result[0].member_id)
    return True
  except AttributeError:
    logging.error(memberId + " is not in the datastore")
    return False
    
def updateScore(memberId,score):
  query = Contacts.all()
  query.filter('member_id =', memberId)
  result = query.fetch(limit=1)
  if len(result) == 0:
    logging.error(memberId + " is not in the datastore")
    return False

  currScore = result[0].high_score
  logging.error("Updating total score from: " + str(currScore))
  currScore += int(score)
  logging.error(", to: " + str(currScore))
  result[0].high_score = currScore
  result[0].put()
  return currScore

  
"""
Queries
"""

def getFirstNameQuery(memberId):
  return getNameQuery(memberId,'first_name')
  
def getLastNameQuery(memberId):
  return getNameQuery(memberId,'last_name')
    
def getPublicationQuery(memberId):
  return getWhoHasAQuery(memberId,'publications')

def getPatentsQuery(memberId):
  return getWhoHasAQuery(memberId,'patents')
  
def leaderboardQuery():
  # fetch top ten from the db
  q = Contacts.all()
  q.order("-high_score")
  results = q.fetch(10)
  logging.error(results)
  return results
  
"""
Helper Methods
"""

def getNameQuery(memberId,whichName): 
  contact_list = getContactList(memberId)

  result_list = []
  
  if len(contact_list) < 4:
    logging.error("You do not have enough contacts to form a question!")
    return "You do not have enough contacts to form a question!"
    
  while len(result_list) < 4:
    ran = random.randint(0,len(contact_list)-1)
    logging.error("ran: " + str(ran))
    contactId = contact_list[ran]
    contactQuery = Person.all()
    contactQuery.filter('member_id =', contactId)
    new_result = contactQuery.fetch(limit=1)
    if len(new_result) > 0:
      if whichName == 'first_name':
        name,pic = new_result[0].first_name,new_result[0].pic_url
      else:
        name,pic = new_result[0].last_name,new_result[0].pic_url
      logging.error("name: " + str(name))
      if (name,pic) not in result_list:
        result_list.append((name,pic))
        logging.error("Adding an answer for " + contactId + " with name " + name)
    else:
      logging.error("Couldn't find name for " + contactId)

  logging.error("Results from getNameQuery: " + str(result_list))                           
                              
  return result_list
  
def getWhoHasAQuery(memberId,which):
  contact_list = getContactList(memberId)

  result_list = []

  if len(contact_list) < 4:
    logging.error("You do not have enough contacts to form a question!")
    return False

  while len(result_list) < 4:
    if len(contact_list) == 0:
      logging.error("You do not have enough contacts with this attribute to form a question!")
      return False 
    ran = random.randint(0,len(contact_list)-1)
    logging.error("ran: " + str(ran))
    contactId = contact_list.pop(ran)
    contactQuery = Person.all()
    contactQuery.filter('member_id =', contactId)
    new_result = contactQuery.fetch(limit=1)
    if len(new_result) > 0:
      if which == 'publications':
        memberId,param,pic = new_result[0].member_id,new_result[0].publications,new_result[0].pic_url
      elif which == 'patents':
        memberId,param,pic = new_result[0].member_id,new_result[0].patents,new_result[0].pic_url
      else:
        return False
      if len(result_list) == 0 and not len(param) == 0:
        result_list.append((True,pic))
      elif not len(result_list) == 0 and len(param) == 0:
        result_list.append((False,pic))
    else:
      logging.error("Couldn't find info for " + contactId)

  logging.error("Results from getAttributeQuery: " + str(result_list))                           

  return result_list

def getContactList(memberId):
  query = Contacts.all()
  query.filter('member_id =', memberId)
  result = query.fetch(limit=1)
  contact_list = result[0].contact_list
  logging.error("contactLisit: " + str(result[0].contact_list))
  return contact_list
  

